/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package CSC.NCSU.EDU;

import com.sun.spot.sensorboard.EDemoBoard;
import com.sun.spot.sensorboard.io.IScalarInput;
import com.sun.spot.sensorboard.io.IScalarInputThresholdListener;

/**
 *
 * @author JaredSmith
 */
public class IRSensor implements IScalarInputThresholdListener {

    public static final int HIGH = 600;
    public static final int LOW = 300;
    private static final int THRESHOLD = (HIGH + LOW) / 2;
    private static final int MIN_VALUE = 0;
    private static final int MAX_VALUE = 1023;

    private IScalarInput pin;

    private int counter;

    public IRSensor(IScalarInput pin) {

        counter = 0;
        this.pin = pin;

        pin.setThresholds(LOW, HIGH);
       // Must enable the threshold events
        pin.enableThresholdEvents(true);
       // Add one listener
        pin.addIScalarInputThresholdListener((IScalarInputThresholdListener) this);


    }

    public void thresholdExceeded(IScalarInput pin, int val) {
        /**
         * These print statements were used for debugging. They printed out
         * whenever a threshold was excided, what the value was, what the ranges
         * were, and the time that the event fired.
         *
        System.out.println(pin.getIndex().toString() + " fired a threshold event.");
        System.out.println("Value = " + val);
        System.out.println("Thresholds: lower = " + pin.getLowThreshold() + " higher = " + pin.getHighThreshold());
        System.out.println("Time = " + System.currentTimeMillis());
        */
        synchronized(this) {
            /**
             * This is a vital part of the program that will keep the spot
             * from firing two events while in the same range. I noticed that it
             * took some time for the spot to realized that I had changed the
             * thresholds and so it would fire an event even though the value
             * sent to the method was not within the range that I had set it to.
             *
             * e.g. Value = 700, Threshold: lower = 300 higher = 1020
             *
             * With the thresholds at 300 and 1020, the spot will be looking for
             * values lower than 300 and higher than 1020. This makes no sense
             * because the value is 700 so it should not have fired and event.
             * This little if statement at the beginning checks for this problem.
             * If the event was triggered and the value is not within the proper
             * ranges, then we do not increment the count and call
             * enableThresholdEvents(true) so that the new thresholds are sent
             * through again.
             */
            if (val > pin.getLowThreshold() && val < pin.getHighThreshold()) {
                pin.enableThresholdEvents(true);
                //used for debugging
                //System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
    		return;
            }
            /**
             * Since we did not return from the if statement above, the first
             * thing we want to do is increment the counter.
             */
            counter++;
            /**
             * Now we must check to see what the IR sensor is looking at. We will
             * use THRESHOLD = (HIGH + LOW)/2 to decide if we are looking at
             * black or white. Anything above THRESHOLD is black while anything
             * below it is white.
             *
             * If we have just incremented the counter because
             * we are looking at black, then we want to change the thresholds so
             * that the next event fired will have the thresholds to fire an
             * event for white.
             *
             * If we have just incremented the counter because we are looking at
             * white, then we want to change the thresgolds so that the next event
             * fired will have the thresholds to fire an event for black.
             *
             * More detail in the theory of operation for IR sensor control
             * using the Sun SPOT.
             */
            if(val > THRESHOLD) {
                pin.setThresholds(LOW, MAX_VALUE);
            }
            else {
                pin.setThresholds(MIN_VALUE, HIGH);
            }
            //We want to make sure the spot knows that we have changed
            //the thresholds.
            pin.enableThresholdEvents(true);
        }
        //used for debugging
        //System.out.println("Counter = " + rightCounter);
        //System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
    }

    public void thresholdChanged(IScalarInput pin, int low, int high) {
        /** Nothing needs to go in here. If you really wanted, you could move
         * the pin.enableThresholdEvents(true); call at the end of
         * thresholdExceeded() into here, but it makes no difference.
         */
    }

    public int getCount() {
        synchronized(this) {
            return counter;
        }
    }

    public void clearCount() {
        synchronized(this) {
            counter = 0;
        }
    }

    
}
